package org.asiainfo.common.log.event;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.asiainfo.common.core.constant.CacheNames;
import org.asiainfo.common.core.constant.Constants;
import org.asiainfo.common.core.utils.ServletUtils;
import org.asiainfo.common.core.utils.StringUtils;
import org.asiainfo.common.core.utils.ip.AddressUtils;
import org.asiainfo.system.api.RemoteClientService;
import org.asiainfo.system.api.RemoteLogService;
import org.asiainfo.system.api.domain.bo.RemoteLoginInfoBo;
import org.asiainfo.system.api.domain.bo.RemoteOperationLogBo;
import org.asiainfo.system.api.domain.vo.RemoteClientVo;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

/**
 * 异步调用日志服务
 */
@Component
@Slf4j
public class LogEventListener {

    @DubboReference
    private RemoteLogService remoteLogService;
    @DubboReference
    private RemoteClientService remoteClientService;

    /**
     * 保存系统日志记录
     */
    @Async
    @EventListener
    public void saveLog(OperatorLogEvent operatorLogEvent) {
        RemoteOperationLogBo remoteOperationLogBo = BeanUtil.toBean(operatorLogEvent, RemoteOperationLogBo.class);
        remoteLogService.saveLog(remoteOperationLogBo);
    }

    @Async
    @EventListener
    public void saveLoginInfo(LoginInfoEvent loginInfoEvent) {
        HttpServletRequest request = loginInfoEvent.getRequest();
        UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
        String ip = ServletUtils.getClientIP(request);
        // 客户端信息
        String clientId = request.getHeader(CacheNames.CLIENT_KEY);
        RemoteClientVo clientVo = null;
        if (StringUtils.isNotBlank(clientId)) {
            clientVo = remoteClientService.queryByClientId(clientId);
        }

        String address = AddressUtils.getRealAddressByIP(ip);
        String s = getBlock(ip) + address
            + getBlock(loginInfoEvent.getUsername())
            + getBlock(loginInfoEvent.getStatus())
            + getBlock(loginInfoEvent.getMessage());
        // 打印信息到日志
        log.info(s, loginInfoEvent.getArgs());
        // 获取客户端操作系统
        String os = userAgent.getOs().getName();
        // 获取客户端浏览器
        String browser = userAgent.getBrowser().getName();
        // 封装对象
        RemoteLoginInfoBo loginInfo = new RemoteLoginInfoBo();
        loginInfo.setTenantId(loginInfoEvent.getTenantId());
        loginInfo.setUserName(loginInfoEvent.getUsername());
        if (ObjectUtil.isNotNull(clientVo)) {
            loginInfo.setClientKey(clientVo.getClientKey());
            loginInfo.setDeviceType(clientVo.getDeviceType());
        }
        loginInfo.setIpaddr(ip);
        loginInfo.setLoginLocation(address);
        loginInfo.setBrowser(browser);
        loginInfo.setOs(os);
        loginInfo.setTenantId(loginInfoEvent.getTenantId());
        loginInfo.setMsg(loginInfoEvent.getMessage());
        // 日志状态
        if (StringUtils.equalsAny(loginInfoEvent.getStatus(), Constants.LOGIN_SUCCESS, Constants.LOGOUT, Constants.REGISTER)) {
            loginInfo.setStatus(Constants.SUCCESS);
        } else if (Constants.LOGIN_FAIL.equals(loginInfoEvent.getStatus())) {
            loginInfo.setStatus(Constants.FAIL);
        }
        remoteLogService.saveLoginInfo(loginInfo);
    }

    private String getBlock(Object msg) {
        if (msg == null) {
            msg = "";
        }
        return "[" + msg + "]";
    }
}
